﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using YasharEl.Infrastructure.EntityModel;
using YasharEl.Infrastructure.EntityModel.Specifications;
using NHibernate;
using NHibernate.Criterion;
using System.Linq.Expressions;
using NHibernate.Impl;

namespace YasharEl.Infrastructure.PersistenceModel.NHibernate.Specifications
{
    public abstract class CriteriaSpecification<TEntity, TIdentity> : ISpecification<TEntity, TIdentity>
        where TEntity : class, IGenericEntity<TIdentity>
    {
        /// <summary>
        /// Gets criteria specification.
        /// </summary>
        protected ICriteria Criteria { get; private set; }

        /// <summary>
        /// Initializes criteria for the specification.
        /// </summary>
        public void Initialize(IUnitOfWork unitOfWork)
        {
            this.Criteria = (unitOfWork as NHibernateUnitOfWork).Session.CreateCriteria<TEntity>();
        }

        /// <summary>
        /// Gets <see cref="CriteriaSpecificationResult"/>.
        /// </summary>
        /// <returns></returns>
        public ISpecificationResult<TEntity, TIdentity> ToResult()
        {
            return new CriteriaSpecificationResult<TEntity, TIdentity>(this.Criteria);
        }

        public ISpecification<TEntity, TIdentity> Where(Expression<Func<TEntity, bool>> expression)
        {
            ICriterion criterion = ExpressionProcessor.ProcessExpression<TEntity>(expression);
            this.Criteria.Add(criterion);

            return this;

        }


    }
}
